/*
 * Copyright (C) 2008-2010 Oliver Horn.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.funcj.tuples;


/**
 * A tuple is a heterogeneous sequence with a fixed number of elements (or components).
 *
 * @author Oliver Horn
 *
 * @see Tuples
 * @see Pairs
 */
public interface Tuple {

	/**
	 * Returns the arity (the number of components) of this tuple.  The arity of a tuple
	 * does not change during the tuple's lifetime.
	 *
	 * @return arity of this tuple
	 */
	public abstract int arity();

	/**
	 * Returns an array containing the elements of this tuple. The order is preserved.
	 * The {@code length} of the array is equal to this tuple's {@link #arity()}.
	 *
	 * <p>The returned array will be "safe" in that no references to it are maintained
	 * by this tuple. (In other words, this method must allocate a new array even if
	 * this tuple is backed by an array). The caller is thus free to modify the returned
	 * array.
	 *
	 * @return an array containing the elements of this tuple
	 */
	public abstract Object[] toArray();

    /**
     * Returns the hash code value for this tuple.  The hash code of a tuple is defined
     * as:
     *
     * <pre>  java.util.Arrays.hashCode(this.toArray())</pre>
     *
     * @see java.util.Arrays#hashCode(Object[])
     * @return the hash code value for this tuple
	 */
	public abstract int hashCode();

	/**
	 * Compares the specified object with this tuple for equality.
	 * Returns {@code true} if and only if the specified object is also a tuple, both
	 * tuples have the same arity, and all corresponding elements in the two tuples
	 * are <i>equal</i>.
	 * @param obj object to be compared for equality with this tuple
	 * @return {@code true} if the specified object is equal to this tuple
	 */
	public abstract boolean equals(Object obj);
}
